<!-- 广告管理页面 -->
<template>
    <div>
        <div class="grid-content">
            <el-select v-model="data.status" placeholder="请选择广告状态" clearable>
                <el-option v-for="item in advStatusMap" :key="item.value" :label="item.name" :value="item.value" />
            </el-select>
            <el-select v-model="data.type" placeholder="请选择广告类型" clearable>
                <el-option v-for="item in advTypeMap" :key="item.value" :label="item.name" :value="item.value" />
            </el-select>
            <el-button type="primary" :icon="Search" @click="init">查找</el-button>
            <el-button type="primary" :icon="Plus" @click="handlePageAdd"
                v-permission="'promotion:advert:create'">添加</el-button>
        </div>
        <el-table :data="tableData" border style="width: 100%" :cell-style="{ textAlign: 'center' }"
            :header-cell-style="{ 'text-align': 'center' }">
            <el-table-column prop="id" label="广告ID" width="80" />
            <el-table-column prop="title" label="广告标题" />
            <el-table-column label="广告图片">
                <template #default="scope">
                    <el-popover v-if="scope.row.imgUrl && scope.row.imgUrl != defaultPic" trigger="hover"
                        placement="right-start" width="300px">
                        <template #default>
                            <el-image :src="scope.row.imgUrl" />
                        </template>
                        <template #reference>
                            <el-image :src="scope.row.imgUrl" style="height: 70px;" />
                        </template>
                    </el-popover>
                    <el-tag v-else type="info">类型无需图片</el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="name" label="广告类型" width="150">
                <template #default="scope">
                    <el-tag>
                        {{ handleAdvType(scope.row.type) }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="name" label="广告状态">
                <template #default="scope">
                    <el-tag :type="scope.row.status == 1 ? 'success' : 'danger'">
                        {{ scope.row.status == 1 ? '激活' : '冻结' }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="name" label="关联类型">
                <template #default="scope">
                    <el-tag type="warning">
                        {{ handleUinonType(scope.row.unionType) }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="unionValue" label="关联值[ID]" />
            <el-table-column label="创建时间" width="180">
                <template #default="scope">
                    {{ formatTime(scope.row.gmtCreate) }}
                </template>
            </el-table-column>
            <el-table-column label="操作" width="200">
                <template #default="scope">
                    <el-button type="primary" @click="handleEdit(scope.$index, scope.row)"
                    v-permission="'promotion:advert:edit'">
                        编辑
                    </el-button>
                    <el-button type="danger" @click="handleDelete(scope.$index, scope.row)"
                    v-permission="'promotion:advert:delete'">
                        删除
                    </el-button>
                </template>
            </el-table-column>
        </el-table>
        <Pagination v-bind="pagination" @page-change="handlePageChange" /><!--分页器-->
        <!-- 添加&编辑弹框 -->
        <el-dialog v-model="dialogFormVisible" :title="dialogTitle" width="600">
            <el-form :model="form" label-position="left" label-width="80px" ref="ruleFormRef" :rules="rules">
                <el-form-item label="广告标题" prop="title">
                    <el-input v-model="form.title" />
                </el-form-item>
                <el-form-item label="广告类型" prop="type">
                    <el-select v-model="form.type" placeholder="请选择广告类型" clearable @clear="unionTypeClear">
                        <el-option v-for="item in advTypeMap" :key="item.value" :label="item.name" :value="item.value"
                            @click="setAdvType(item)" />
                    </el-select>
                </el-form-item>
                <el-form-item label="广告图片" v-if="isPic && form.type" id="uploadImg" prop="imgUrl"
                    :style='{ background: form.color }'>
                    <el-upload class="avatar-uploader" action="http://192.168.1.188:8080/upload/admin"
                        :headers="headers" :show-file-list="false" :on-success="handleAvatarSuccess"
                        :before-upload="beforeAvatarUpload">
                        <img v-if="form.imgUrl" :src="form.imgUrl" class="avatar" />
                        <el-icon v-else class="avatar-uploader-icon">
                            <Plus />
                        </el-icon>
                    </el-upload>
                </el-form-item>
                <el-form-item label="广告状态" prop="status">
                    <el-switch v-model="form.status" :active-value='1' :inactive-value='0' active-color="#13ce66" />
                </el-form-item>
                <el-form-item label="关联类型" prop="unionType">
                    <el-select v-model="form.unionType" :disabled="!form.type"
                        :placeholder="form.type ? '点击时跳转目标' : '请选择广告类型'" clearable>
                        <el-option v-for="(item, index) in advUinonTypeMap" :key="item.value" :label="item.name"
                            :disabled="advType[index] == item.value ? false : true" :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="商品" v-if="form.unionType === 1 && form.type" prop="unionValue">
                    <el-cascader v-model="form.unionValue" placeholder="关联至商品" :options="goodsTreeData" clearable
                        :props="{ emitPath: false, label: 'label', value: 'id', children: 'children' }" />
                </el-form-item>
                <el-form-item label="类目" v-if="form.unionType === 2 && form.type" prop="unionValue">
                    <el-cascader v-model="form.unionValue" placeholder="关联至类目" :options="categoryTreeData" clearable
                        :props="{ emitPath: false, label: 'title', value: 'id', children: 'childrenList' }" />
                </el-form-item>
                <el-form-item label="关键字" v-if="form.unionType === 3 && form.type" prop="unionValue">
                    <el-input v-model="form.unionValue" />
                </el-form-item>
                <el-form-item label="功能页面" v-if="form.unionType === 4 && form.type" prop="unionValue">
                    <el-select v-model="form.unionValue" placeholder="请选择一个页面功能" clearable>
                        <el-option v-for="item in functionPages" :key="item.value" :label="item.name"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="dialogFormVisible = false">取消</el-button>
                    <el-button type="primary" @click="determine(ruleFormRef)">
                        确定
                    </el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted, computed } from "vue";
import { Search, Plus } from '@element-plus/icons-vue';//图标 
import { post, get } from "@/utils/http"; //封装的axios请求方式
import { formatTime } from "@/utils/time";//处理时间
import cookie from 'js-cookie'//引入处理cookies的Api
import { PaginationClass, AdvertClass } from "#/index";//数据类型
import { ElMessage, ElMessageBox } from 'element-plus'//提示信息
import type { UploadProps, FormInstance } from 'element-plus'//上传类型数据
import { setImageColor } from '@/utils/ImageColor'//获取设置上传图片的背景颜色

const ruleFormRef = ref<FormInstance>()//操作form节点
const pagination = ref(new PaginationClass())//分页数据
const tableData = ref([])//表格数据
const goodsTreeData = ref([])//商品树形菜单数据
const categoryTreeData = ref([])//类目树形菜单数据
const dialogFormVisible = ref(false)//控制弹框显示隐藏
const advType = ref([] as any)//根据广告类型判断是否禁用关联类型
const defaultPic = 'https://img-blog.csdnimg.cn/7dd7282e4bf4410bb64d652a7436f09d.png'//默认图片
const headers = reactive({ 'AdminToken': cookie.get('token') })//头像上传添加token头
const advTypeMap = reactive([//广告类型
    { value: 1, unionTypes: [1, 2, 3, 4], picRequire: true, name: '轮播' },
    { value: 2, unionTypes: [0, 2], picRequire: true, name: '分类精选' },
    { value: 3, unionTypes: [1, 2, 3, 4], picRequire: true, name: '横幅' },
    { value: 4, unionTypes: [1, 2, 3, 4], picRequire: true, name: '首页轮播下5按钮' },
    { value: 6, unionTypes: [1, 2, 3, 4], picRequire: false, name: '公告' },
    { value: 9, unionTypes: [1], picRequire: false, name: '商品推荐' }
])
const advStatusMap = reactive([//广告状态
    { value: 0, name: '冻结' },
    { value: 1, name: '激活' }
])
const advUinonTypeMap = reactive([//广告关联类型
    { value: 1, name: '商品' },
    { value: 2, name: '类目' },
    { value: 3, name: '关键字' },
    { value: 4, name: '功能页面' }
])
const functionPages = reactive([//页面功能
    { value: '/pages/product/groupshop', name: '团购列表' },
    { value: '/pages/coupon/list', name: '优惠券列表' },
])
const rules = reactive({// 表单验证
    title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
    type: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
    imgUrl: [{ required: true, message: '图片不能为空', trigger: 'blur' }],
    status: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
    unionType: [{ required: true, message: '关联不能为空', trigger: 'blur' }],
    unionValue: [{ required: true, message: '关联内容不能为空', trigger: 'blur' }],
})

let dialogTitle = computed(() => dialogType.value == false ? '创建' : '编辑')//判断弹框标题
let dialogType = ref(false)//控制弹框类型
let form = ref(new AdvertClass())//弹框绑定数据
let isPic = ref(false)//判断广告图片隐藏显示
let data = ref({//请求传递的数据
    _gp: 'admin.advert',
    _mt: 'list',
    type: '',//广告类型
    status: '',//广告状态
    pageNo: 1,//当前的页数
    limit: 10//每页显示条数
})

onMounted(() => {
    init()
})

// 初始化数据
function init() {
    post(data.value).then((res) => {
        console.log(res);
        let { data: { items, total } } = res;
        tableData.value = items;//表格数据赋值
        pagination.value.total = total;//总页数赋值
    })
    GoodsTreeInfo()
    CategoryTreeInfo()
}

// 初始化商品树形菜单数据
function GoodsTreeInfo() {
    post({ _gp: 'admin.product', _mt: 'getSpuBigTree' }).then((res) => {
        console.log(res);
        let { data } = res;
        goodsTreeData.value = data
    })
}
// 初始化类目树形菜单数据
function CategoryTreeInfo() {
    post({ _gp: 'admin.category', _mt: 'categoryTree' }).then((res) => {
        console.log(res);
        let { data } = res;
        categoryTreeData.value = data
    })
}

// 广告类型处理
function setAdvType(row: any) {
    isPic.value = row.picRequire;
    advType.value = row.unionTypes
    // 选中不同的广告类型，出现对应的关联类型
    for (const i in advUinonTypeMap) {
        if (advUinonTypeMap[i].value == row.unionTypes[i]) {
            advType.value = row.unionTypes
        } else {
            form.value.unionType = undefined
        }
    }
    // 判断是添加弹框
    if (dialogType.value == false) {
        if (row.value == 6 || row.value == 9) {
            form.value.imgUrl = defaultPic;
        } else {
            form.value.imgUrl = ''
        }
    }
}

// 头像上传
const handleAvatarSuccess: UploadProps['onSuccess'] = (
    response
) => {
    form.value.imgUrl = response.url;
    setImageColor(form.value.imgUrl, (e: string) => {
        form.value.color = e
    })
}

// 验证头像上传规则
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
    if (rawFile.type !== 'image/jpeg') {
        ElMessage.error('头像图片必须是JPG格式!')
        return false
    } else if (rawFile.size / 1024 / 1024 > 2) {
        ElMessage.error('Avatar picture size can not exceed 2MB!')
        return false
    }
    return true
}

// 处理广告类型
function handleAdvType(type: number) {
    for (const i of advTypeMap) {
        if (type == i.value) {
            return i.name
        }
    }
}

// 处理关联类型
function handleUinonType(type: number) {
    for (const i of advUinonTypeMap) {
        if (type == i.value) {
            return i.name
        }
    }
}

// 清空广告类型触发重置关联类型
function unionTypeClear() {
    if (dialogType.value == false) {
        form.value.unionType = undefined
    }
}

// 添加
function handlePageAdd() {
    dialogType.value = false;//定义弹框类型
    dialogFormVisible.value = true;//显示弹框
    form.value = <AdvertClass>{};//清空form表单数据
    ruleFormRef.value?.resetFields();//重置表单初始值
    isPic.value = false;//重置广告图片隐藏显示数据
}

// 编辑
function handleEdit(index: number, row: any) {
    dialogType.value = true;//定义弹框类型
    dialogFormVisible.value = true;//显示弹框
    ruleFormRef.value?.resetFields();//重置表单初始值
    form.value = { ...row, adId: row.id }
    //判断如果是默认图片是则不显示上传图片
    row.imgUrl == defaultPic ? isPic.value = false : isPic.value = true;
    // 转数字类型；映射到级联控件
    if (1 === row.unionType || 2 === row.unionType) {
        form.value.unionValue = +form.value.unionValue
    }
    // 查找广告类型里广告关联数组判断是否相等
    let itme = advTypeMap.find(i => i.value == row.type)
    advType.value = itme?.unionTypes
}

// 弹框确定
function determine(formEl: FormInstance | undefined) {
    if (!formEl) return
    formEl.validate((valid: boolean) => {
        if (valid) {
            post({
                _gp: 'admin.advert',
                _mt: dialogType.value == false ? 'create' : 'edit',
                ...form.value
            }).then((res) => {
                let { errmsg, errno } = res;
                200 == errno ? ElMessage.success(dialogType.value == false ? '添加成功!' : '编辑成功!') : ElMessage.error(errmsg);
                dialogFormVisible.value = false;//隐藏弹框
                init()
            })
        } else {
            return false
        }
    })
}

// 删除
function handleDelete(index: number, row: any) {
    ElMessageBox.confirm(
        '确定要删除吗?',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
        }
    ).then(() => {
        get({ _gp: 'admin.advert', _mt: 'delete', type: row.type, adId: row.id }).then((res) => {
            console.log(res);
            let { errmsg, errno } = res
            200 == errno ? ElMessage.success('删除已完成') : ElMessage.error(errmsg)
            init()
        })
    }).catch(() => {
        ElMessage.info('删除已取消')
    })
}

// 分页组件里的数据赋值
function handlePageChange(v: PaginationClass) {
    data.value.pageNo = v.page
    data.value.limit = v.limit
    init()
}
</script>
<style lang="less" scoped>
.grid-content {
    display: flex;
    margin-bottom: 20px;

    .el-select {
        margin-right: 8px;
    }

    .el-button {
        margin: 0px 8px 0px 0px;
    }
}

.el-form {
    margin: auto;
    width: 400px;

    .avatar {
        width: 178px;
        height: 178px;
    }
}
</style>

